{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "061VwlZpO9Lq"
   },
   "source": [
    "# MONAI Network APIs\n",
    "---\n",
    "\n",
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/master/modules/network_api.ipynb)\n",
    "\n",
    "\n",
    "### Overview\n",
    "\n",
    "This notebook introduces you to the MONAI network APIs:\n",
    "- Convolutions\n",
    "- Specifying layers with additional arguments\n",
    "- Flexible definitions of networks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9ERmUzC3O9Lr"
   },
   "source": [
    "## Install MONAI and import dependecies\n",
    "This section installs the latest version of MONAI and validates the install by printing out the configuration.\n",
    "\n",
    "We'll then import our dependencies and MONAI.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "!python -c \"import monai\" || pip install -q \"monai-weekly\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 340
    },
    "colab_type": "code",
    "id": "PWt0e0QPO9Lr",
    "outputId": "9667fc7d-f363-4940-9106-7649dbb34dc7",
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MONAI version: 0.6.0+27.gaaeebd62\n",
      "Numpy version: 1.21.0\n",
      "Pytorch version: 1.9.0\n",
      "MONAI flags: HAS_EXT = False, USE_COMPILED = False\n",
      "MONAI rev id: aaeebd62e297b64ee7b5e3fccd415ed0aacba4cf\n",
      "\n",
      "Optional dependencies:\n",
      "Pytorch Ignite version: 0.4.5\n",
      "Nibabel version: 3.2.1\n",
      "scikit-image version: 0.18.2\n",
      "Pillow version: 8.2.0\n",
      "Tensorboard version: 2.4.1\n",
      "gdown version: 3.13.0\n",
      "TorchVision version: 0.10.0\n",
      "tqdm version: 4.61.1\n",
      "lmdb version: 1.2.1\n",
      "psutil version: 5.8.0\n",
      "pandas version: 1.1.5\n",
      "einops version: 0.3.0\n",
      "\n",
      "For details about installing the optional dependencies, please visit:\n",
      "    https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import monai\n",
    "from monai.networks.layers import Conv\n",
    "from monai.networks.layers import Act\n",
    "from monai.networks.layers import split_args\n",
    "from monai.networks.layers import Pool\n",
    "from monai.networks.layers import get_act_layer\n",
    "\n",
    "monai.config.print_config()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "3RKwDaMQNrQj"
   },
   "source": [
    "## Unifying the network layer APIs\n",
    "\n",
    "Network functionality represents a major design opportunity for MONAI. Pytorch is very much unopinionated in how networks are defined. It provides Module as a base class from which to create a network, and a few methods that must be implemented, but there is no prescribed pattern nor much helper functionality for initializing networks. \n",
    "\n",
    "This leaves a lot of room for defining some useful 'best practice' patterns for constructing new networks in MONAI. Although trivial, inflexible network implementations are easy enough, we can give users a toolset that makes it much easier to build well-engineered, flexible networks, and demonstrate their value by committing to use them in the networks that we build."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "lmh9WcfRUd2s"
   },
   "source": [
    "### Convolution as an example\n",
    "\n",
    "We'll start by taking a look at the Convolution `__doc__` string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 51
    },
    "colab_type": "code",
    "id": "TFgdtWLBPkJC",
    "outputId": "e1e23a64-0ea2-40bc-813c-6a892b06cb13"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The supported members are: ``CONV``, ``CONVTRANS``.\n",
      "Please see :py:class:`monai.networks.layers.split_args` for additional args parsing.\n"
     ]
    }
   ],
   "source": [
    "print(Conv.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Y3y2qGhgRYXI"
   },
   "source": [
    "The [Conv](https://docs.monai.io/en/latest/networks.html#convolution) class has two options for the first argument. The second argument must be the number of spatial dimensions, `Conv[name, dimension]`, for example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 119
    },
    "colab_type": "code",
    "id": "3rZ21AMDRlIP",
    "outputId": "b2b1e92c-b489-4326-b4a8-e9cb522a10be"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'torch.nn.modules.conv.Conv1d'>\n",
      "<class 'torch.nn.modules.conv.Conv2d'>\n",
      "<class 'torch.nn.modules.conv.Conv3d'>\n",
      "<class 'torch.nn.modules.conv.ConvTranspose1d'>\n",
      "<class 'torch.nn.modules.conv.ConvTranspose2d'>\n",
      "<class 'torch.nn.modules.conv.ConvTranspose3d'>\n"
     ]
    }
   ],
   "source": [
    "print(Conv[Conv.CONV, 1])\n",
    "print(Conv[Conv.CONV, 2])\n",
    "print(Conv[Conv.CONV, 3])\n",
    "print(Conv[Conv.CONVTRANS, 1])\n",
    "print(Conv[Conv.CONVTRANS, 2])\n",
    "print(Conv[Conv.CONVTRANS, 3])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "EPAuW45_TKBR"
   },
   "source": [
    "The configured classes are the \"vanilla\" PyTorch layers. We could create instances of them by specifying the layer arguments:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 51
    },
    "colab_type": "code",
    "id": "rYTaJuS-TvZA",
    "outputId": "b8398d90-81c1-42f3-c03e-25c624b99465"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Conv2d(1, 4, kernel_size=(3, 3), stride=(1, 1))\n",
      "Conv3d(1, 4, kernel_size=(3, 3, 3), stride=(1, 1, 1))\n"
     ]
    }
   ],
   "source": [
    "print(Conv[Conv.CONV, 2](in_channels=1, out_channels=4, kernel_size=3))\n",
    "print(Conv[Conv.CONV, 3](in_channels=1, out_channels=4, kernel_size=3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "HGthKNI0Um50"
   },
   "source": [
    "### Specifying a layer with additional arguments\n",
    "We'll now take a look at the Activation `__doc__` string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 51
    },
    "colab_type": "code",
    "id": "TJJ6umixUaiP",
    "outputId": "bae28cb9-5cee-4ad5-921f-3609ca706ea1"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The supported members are: ``ELU``, ``RELU``, ``LEAKYRELU``, ``PRELU``, ``RELU6``, ``SELU``, ``CELU``, ``GELU``, ``SIGMOID``, ``TANH``, ``SOFTMAX``, ``LOGSOFTMAX``, ``SWISH``, ``MEMSWISH``, ``MISH``.\n",
      "Please see :py:class:`monai.networks.layers.split_args` for additional args parsing.\n"
     ]
    }
   ],
   "source": [
    "print(Act.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "0NCmNkLcV9np"
   },
   "source": [
    "The [Act](https://docs.monai.io/en/latest/networks.html#module-monai.networks.layers.Act) classes don't require the spatial dimension information, but supports additional arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 51
    },
    "colab_type": "code",
    "id": "zQO2PX4TVXU1",
    "outputId": "46932ee7-de00-43ce-be57-c5035cdeade0"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'torch.nn.modules.activation.PReLU'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "PReLU(num_parameters=1)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(Act[Act.PRELU])\n",
    "Act[Act.PRELU](num_parameters=1, init=0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "SE0tKPlyU95d"
   },
   "source": [
    "These could be fully specified with a tuple of `(type_name, arg_dict)`, such as `(\"prelu\", {\"num_parameters\": 1, \"init\": 0.1})`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "BtRCIstVWQkr",
    "outputId": "e39579a4-4f03-411c-ab1c-941c25ff9f00"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PReLU(num_parameters=1)"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "act_name, act_args = split_args((\"prelu\", {\"num_parameters\": 1, \"init\": 0.1}))\n",
    "Act[act_name](**act_args)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, this could be done with the `get_*_layer` interface, to simplify the syntax."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PReLU(num_parameters=1)\n"
     ]
    }
   ],
   "source": [
    "p_layer = get_act_layer(name=(\"prelu\", {\"num_parameters\": 1, \"init\": 0.25}))\n",
    "print(p_layer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UnfMOLx5Xegi"
   },
   "source": [
    "### Putting them together"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "3LzZkQ_7ScHX"
   },
   "source": [
    "These APIs allow for flexible definitions of networks.  Below we'll create a class called `MyNetwork` that utilizes `Conv`, `Act`, and `Pool`.  Each Network requires an `__init__` and a `forward` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "Uc6O3S4WSopx"
   },
   "outputs": [],
   "source": [
    "class MyNetwork(torch.nn.Module):\n",
    "\n",
    "    def __init__(self, dims=3, in_channels=1, out_channels=8, kernel_size=3, pool_kernel=2, act=\"relu\"):\n",
    "        super(MyNetwork, self).__init__()\n",
    "        # convolution\n",
    "        self.conv = Conv[Conv.CONV, dims](in_channels, out_channels, kernel_size=kernel_size)\n",
    "        # activation\n",
    "        act_type, act_args = split_args(act)\n",
    "        self.act = Act[act_type](**act_args)\n",
    "        # pooling\n",
    "        self.pool = Pool[Pool.MAX, dims](pool_kernel)\n",
    "\n",
    "    def forward(self, x: torch.Tensor):\n",
    "        x = self.conv(x)\n",
    "        x = self.act(x)\n",
    "        x = self.pool(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Wr1ilIJvayFo"
   },
   "source": [
    "This network definition can be instantiated to support either 2D or 3D inputs, with flexible kernel sizes.\n",
    "\n",
    "It becomes handy when adapting the same architecture design for different tasks,\n",
    "switching among 2D, 2.5D, 3D easily."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 323
    },
    "colab_type": "code",
    "id": "ddRgmz-9ap2b",
    "outputId": "540bcf09-9f85-456f-c9a5-cc0197c68f67"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MyNetwork(\n",
      "  (conv): Conv3d(1, 8, kernel_size=(3, 3, 3), stride=(1, 1, 1))\n",
      "  (act): ReLU()\n",
      "  (pool): MaxPool3d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      ")\n",
      "torch.Size([3, 8, 9, 9, 14])\n"
     ]
    }
   ],
   "source": [
    "# default network instance\n",
    "default_net = MyNetwork()\n",
    "print(default_net)\n",
    "print(default_net(torch.ones(3, 1, 20, 20, 30)).shape)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2D network instance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MyNetwork(\n",
      "  (conv): Conv2d(3, 8, kernel_size=(3, 3), stride=(1, 1))\n",
      "  (act): ELU(alpha=1.0, inplace=True)\n",
      "  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      ")\n",
      "torch.Size([3, 8, 11, 11])\n"
     ]
    }
   ],
   "source": [
    "elu_net = MyNetwork(dims=2, in_channels=3, act=(\"elu\", {\"inplace\": True}))\n",
    "print(elu_net)\n",
    "print(elu_net(torch.ones(3, 3, 24, 24)).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3D network instance with anisotropic kernels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MyNetwork(\n",
      "  (conv): Conv3d(4, 8, kernel_size=(3, 3, 1), stride=(1, 1, 1))\n",
      "  (act): Sigmoid()\n",
      "  (pool): MaxPool3d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      ")\n",
      "torch.Size([3, 8, 14, 14, 2])\n"
     ]
    }
   ],
   "source": [
    "sigmoid_net = MyNetwork(3, in_channels=4, kernel_size=(3, 3, 1), act=\"sigmoid\")\n",
    "print(sigmoid_net)\n",
    "print(sigmoid_net(torch.ones(3, 4, 30, 30, 5)).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "3AszY4ttlRut"
   },
   "source": [
    "Almost all the MONAI layers, blocks and networks are extensions of `torch.nn.modules` and follow this pattern. This makes the implementations compatible with any PyTorch pipelines and flexible with the network design.\n",
    "The current collections of those differentiable modules are listed in https://docs.monai.io/en/latest/networks.html."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### AHNet\n",
    "\n",
    "Among those implementations, MONAI features a 3D anisotropic hybrid network (AHNet) with the anisotropic encoder kernels initialised from a pretrained resnet. Please see https://docs.monai.io/en/latest/networks.html#ahnet"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "In this notebook, we recapped MONAI Layers including:\n",
    "- Convolutions and Activations\n",
    "- Putting together a base network\n",
    "- Initialize an AHNet\n",
    "\n",
    "For full API documentation, please visit https://docs.monai.io."
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "lab3_networks.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "081b8157ccdd44feab9714ce98fdb6fc": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "313d9aa40b7248a4887c638eeef7e9e1": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "63538ca5c61543e2a074e12cab6e581a": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": "initial"
     }
    },
    "7f7b548251a943d08e7c6091a96d9bae": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "8463a8ce1803481d94723a4878b29025": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_8a97ddb03f95404cb27a24557043cbaf",
       "IPY_MODEL_cbabc5d60b89408b9284c54ecfc5a8f3"
      ],
      "layout": "IPY_MODEL_7f7b548251a943d08e7c6091a96d9bae"
     }
    },
    "8a97ddb03f95404cb27a24557043cbaf": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "success",
      "description": "100%",
      "description_tooltip": null,
      "layout": "IPY_MODEL_f08147de49e4468da9a8b03fd56cf499",
      "max": 102502400,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_63538ca5c61543e2a074e12cab6e581a",
      "value": 102502400
     }
    },
    "cbabc5d60b89408b9284c54ecfc5a8f3": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_081b8157ccdd44feab9714ce98fdb6fc",
      "placeholder": "​",
      "style": "IPY_MODEL_313d9aa40b7248a4887c638eeef7e9e1",
      "value": " 97.8M/97.8M [00:00&lt;00:00, 215MB/s]"
     }
    },
    "f08147de49e4468da9a8b03fd56cf499": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
